package test.pbking.facebook.delegates
{
	import com.pbking.facebook.Facebook;
	import com.pbking.facebook.delegates.data.CreateObjectDelegate;
	import com.pbking.facebook.delegates.data.CreateObjectTypeDelegate;
	import com.pbking.facebook.delegates.data.GetHashValueDelegate;
	import com.pbking.facebook.delegates.data.GetUserPreferenceDelegate;
	import com.pbking.facebook.delegates.data.IncHashValueDelegate;
	import com.pbking.facebook.delegates.data.RemoveHashKeyDelegate;
	import com.pbking.facebook.delegates.data.RemoveHashKeysDelegate;
	import com.pbking.facebook.delegates.data.SetHashValueDelegate;
	import com.pbking.facebook.delegates.data.SetUserPreferenceDelegate;
	import com.pbking.facebook.delegates.data.UpdateObjectDelegate;
	
	import flash.events.Event;
	
	import flexunit.framework.TestCase;
	import flexunit.framework.TestSuite;
	
	import test.pbking.facebook.Facebook_test;

	public class Data_test extends TestCase
	{
		private static var facebook:Facebook;
		
		private var testPrefId:int = 200;
		private var testPrefValue:String = "test data pref_id 200"; // an arbitrary value.  
		
		private const TEST_OBJ_TYPE:String = "testtype1";
		private const TEST_HASH_KEY:String = "testhashkey1";
		/** property name of a string type property */
		private const TEST_STR_PROP_NAME:String = "testprop1";
		/** prperty value of a string type property */
		private const TEST_STR_PROP_VALUE:String = "value1";
		/** property name of an int type property */
		private const TEST_INT_PROP_NAME:String = "uid";
		/** property value of an int type property */
		private const TEST_INT_PROP_VALUE:int = 10;
		/** increment value used in testing */
		private const INCREMENT:int = 5;
		
		
		public function Data_test(methodName:String=null)
		{
			super(methodName);
		}
		
		public static function suite(testFacebook:Facebook):TestSuite
		{
			facebook = testFacebook;
			
			var ts:TestSuite = new TestSuite();
			
			ts.addTest( new Data_test("testSetUserPreference"));
			//ts.addTest( new Data_test("testGetUserPreference"));
			ts.addTest( new Data_test("testCreateObjectType"));
			ts.addTest( new Data_test("testCreateObject"));
			ts.addTest( new Data_test("testSetHashValue"));
			ts.addTest( new Data_test("testRemoveHashKey"));
			//ts.addTest( new Data_test("testRemoveHashKeys")); // testRemoveHashKeys failed the test.  error code: 805, error msg: "A database error occurred. Please try again: unable to lookup hash keys"
			
			return ts;
		}
		
		/**
		 * Test setUserPreference()
		 */
		public function testSetUserPreference():void
		{
			testPrefValue = new Date().toString();
			facebook.data.setUserPreference(testPrefId, testPrefValue, addAsync(testSetUserPreferenceReply, Facebook_test.timeoutTime));
		}
		private function testSetUserPreferenceReply(e:Event):void
		{
			var d:SetUserPreferenceDelegate = e.target as SetUserPreferenceDelegate;
			assertTrue(d.errorMessage, d.success);
			testGetUserPreference(); // retrieve the value to see if set works.
		}
		
		/**
		 * test getUserPreference()
		 */
		public function testGetUserPreference():void
		{
			facebook.data.getUserPreference(testPrefId, addAsync(testGetUserPreferenceReply, Facebook_test.timeoutTime));
		}
		private function testGetUserPreferenceReply(e:Event):void
		{
			var d:GetUserPreferenceDelegate = e.target as GetUserPreferenceDelegate;
			assertTrue(d.errorMessage, d.success);
			assertEquals(d.preferenceValue, testPrefValue);
		}
		
		/**
		 * note: you need to loggin as application developer.  otherwise, error code 200 "Permissions error"
		 */
		public function testCreateObjectType():void
		{
			facebook.data.createObjectType("testtemp"+new Date().time.toString(), addAsync(testCreateObjectTypeReply, Facebook_test.timeoutTime));
		}
		private function testCreateObjectTypeReply(e:Event):void
		{
			var d:CreateObjectTypeDelegate = e.target as CreateObjectTypeDelegate;
			assertTrue(d.errorMessage, d.success);
		}
		
		public function testCreateObject():void
		{
			var properties:Object = new Object();
  			properties.testprop1 = "testprop1value";
  			properties.uid = 1;
			facebook.data.createObject("testtype1", properties, addAsync(testCreateObjectReply, Facebook_test.timeoutTime));
		}
		private function testCreateObjectReply(e:Event):void
		{
			var d:CreateObjectDelegate = e.target as CreateObjectDelegate;
			assertTrue(d.errorMessage, d.success);
			assertTrue("expected Facebook to return obj_id, which should be larger than 0", d.objid > 0); // check what failed objid would be
			
			testUpdateObject(d.objid); 
		}
		
		public function testUpdateObject(objid:Number):void
		{
			var properties:Object = new Object();
  			properties.uid = 2;
			facebook.data.updateObject(objid, properties, true, addAsync(testUpdateObjectReply, Facebook_test.timeoutTime));
		}
		private function testUpdateObjectReply(e:Event):void
		{
			var d:UpdateObjectDelegate = e.target as UpdateObjectDelegate;
			assertTrue(d.errorMessage, d.success);
		}
		
		public function testSetHashValue():void
		{
			facebook.data.setHashValue(TEST_OBJ_TYPE, TEST_HASH_KEY, TEST_INT_PROP_VALUE.toString(), TEST_INT_PROP_NAME, addAsync(testSetHashValueReply, Facebook_test.timeoutTime));
		}
		private function testSetHashValueReply(e:Event):void
		{
			var d:SetHashValueDelegate = e.target as SetHashValueDelegate;
			assertTrue(d.errorMessage, d.success);
			assertTrue("expected Facebook to return obj_id, which should be larger than 0", d.objid); // expect it to return objid.
			testGetHashValue(); // double verify using getHashValue()
		}
		
		public function testGetHashValue():void
		{
			facebook.data.getHashValue(TEST_OBJ_TYPE, TEST_HASH_KEY, TEST_INT_PROP_NAME, addAsync(testGetHashValueReply, Facebook_test.timeoutTime));
		}
		private function testGetHashValueReply(e:Event):void
		{
			var d:GetHashValueDelegate = e.target as GetHashValueDelegate;
			assertTrue(d.errorMessage, d.success);
			assertEquals("testGetHashValueReply(): getHashValue() should return " + TEST_INT_PROP_VALUE + ".  it returned=" + d.propValue, TEST_INT_PROP_VALUE, d.propValue);
			
			testIncHashValue();
		}
		
		public function testIncHashValue():void
		{
			facebook.data.incHashValue(TEST_OBJ_TYPE, TEST_HASH_KEY, TEST_INT_PROP_NAME, INCREMENT, addAsync(testIncHashValueReply, Facebook_test.timeoutTime));
		}
		private function testIncHashValueReply(e:Event):void
		{
			var d:IncHashValueDelegate = e.target as IncHashValueDelegate;
			var value:int = (TEST_INT_PROP_VALUE + INCREMENT);
			assertTrue(d.errorMessage, d.success);
			assertEquals("testGetHashValueReply(): incHashValue() should return " + value + ".  it returned=" + d.propValue, value, d.propValue); 
			testGetHashValueAfterInc(); // double verify using getHashValue()
		}
		
		/**
		 * get the prop value after increment is done to verify that increment works.  
		 */
		public function testGetHashValueAfterInc():void
		{
			facebook.data.getHashValue(TEST_OBJ_TYPE, TEST_HASH_KEY, TEST_INT_PROP_NAME, addAsync(testGetHashValueAfterIncReply, Facebook_test.timeoutTime));
		}
		private function testGetHashValueAfterIncReply(e:Event):void
		{
			var d:GetHashValueDelegate = e.target as GetHashValueDelegate;
			var value:int = (TEST_INT_PROP_VALUE + INCREMENT);
			assertTrue(d.errorMessage, d.success);
			assertEquals("testGetHashValueAfterIncReply(): getHashValue() should return " + value + ".  it returned=" + d.propValue, value, d.propValue);
		}
		
		/**
		 * emperical result shows: even if a incorrect hashkey is supplied as argument, facebook platform does not return an error.
		 * so if hashkey "testkey123" has never been created by setHashValue().  calling removeHashKey for "testkey123" will not return an error.  
		 */
		public function testRemoveHashKey():void
		{
			facebook.data.removeHashKey(TEST_OBJ_TYPE, TEST_HASH_KEY, addAsync(testRemoveHashKeyReply, Facebook_test.timeoutTime));
		}
		private function testRemoveHashKeyReply(e:Event):void
		{
			var d:RemoveHashKeyDelegate = e.target as RemoveHashKeyDelegate;
			assertTrue(d.errorMessage, d.success);
			
			testGetHashValueAfterRemove(); // double verify that it is removed.
		}
		
		/**
		 * get the prop value after remove is done to verify that remove does remove the key  
		 */
		public function testGetHashValueAfterRemove():void
		{
			facebook.data.getHashValue(TEST_OBJ_TYPE, TEST_HASH_KEY, TEST_INT_PROP_NAME, addAsync(testGetHashValueAfterRemoveReply, Facebook_test.timeoutTime));
		}
		private function testGetHashValueAfterRemoveReply(e:Event):void
		{
			var d:GetHashValueDelegate = e.target as GetHashValueDelegate;
			assertTrue(d.errorMessage, d.success);
			assertEquals("testGetHashValueAfterRemoveReply(): getHashValue() should return null after hashkey is removed.  it returned=" + d.propValue, null, d.propValue);
		}
		
		public function testRemoveHashKeys():void
		{
			facebook.data.removeHashKeys(TEST_OBJ_TYPE, [TEST_HASH_KEY], addAsync(testRemoveHashKeysReply, Facebook_test.timeoutTime));
		}
		private function testRemoveHashKeysReply(e:Event):void
		{
			var d:RemoveHashKeysDelegate = e.target as RemoveHashKeysDelegate;
			assertTrue(d.errorMessage, d.success);
		}
	}
}